import { defineStore } from 'pinia';
import { 
  getCoursesInitGraph, 
  getNodeWithNeighbors, 
  getAllNodeTypes, 
  searchSubgraph, 
  getNodeProperties,
  GraphDTO,
  GraphNodeDTO,
  GraphEdgeDTO
} from '@/api/knowledge-graph';
import { ElMessage } from 'element-plus';

// 定义节点类型接口
interface NodeType {
  type: string;
  name: string;
}

// 定义边类型接口
interface EdgeType {
  type: string;
  name: string;
}

export const useGraphStore = defineStore('graphStore', {
  state: () => ({
    // 节点和边的数据
    graphData: {
      nodes: [] as GraphNodeDTO[],
      edges: [] as GraphEdgeDTO[]
    },
    // 节点类型列表
    nodeTypes: [
      { type: 'Course', name: '课程' },
      { type: 'Case', name: '案例' },
      { type: 'Component', name: '组件' },
      { type: 'Knowledge', name: '知识点' }
    ],
    // 边类型
    edgeTypes: [
      { type: 'PRE_COURSE', name: '前置课程' },
      { type: 'COURSE_KNOWLEDGE', name: '包含知识点' },
      { type: 'PRE_KNOWLEDGE', name: '前置知识点' },
      { type: 'CASE_COMPONENT', name: '包含组件' },
      { type: 'RELATED', name: '关联' }
    ],
    // 当前选中的节点
    currentNode: null as GraphNodeDTO | null,
    // 节点属性信息
    nodeProperties: {} as Record<string, any>,
    // 记录已加载的节点ID，避免重复加载
    loadedNodeIds: new Set<string>(),
    // 记录已经加载的边的唯一标识
    loadedEdgeKeys: new Set<string>(),
    // 搜索相关状态
    searchForm: {
      selectedType: '',
      searchKeyword: ''
    },
    // 加载状态
    loading: false
  }),
  
  actions: {
    /**
     * 获取所有节点类型
     */
    async fetchNodeTypes() {
      try {
        const response = await getAllNodeTypes();
        if (response && response.data) {
          this.nodeTypes = response.data;
        }
      } catch (error) {
        console.error('获取节点类型失败:', error);
        ElMessage.error('获取节点类型失败');
      }
    },

    /**
     * 获取初始图数据
     */
    async fetchInitialGraph() {
      this.loading = true;
      try {
        const response = await getCoursesInitGraph();
        
        if (!response || !response.data) {
          throw new Error('API返回数据格式不正确');
        }

        // 清空现有数据
        this.graphData.nodes = [];
        this.graphData.edges = [];
        this.loadedNodeIds.clear();
        this.loadedEdgeKeys.clear();
        
        this.setGraphData(response.data);
        return true;
      } catch (error) {
        console.error('Failed to load graph data:', error);
        return false;
      } finally {
        this.loading = false;
      }
    },

    /**
     * 搜索子图
     */
    async searchGraph() {
      if (!this.searchForm.selectedType || !this.searchForm.searchKeyword) {
        ElMessage.warning('请选择类型并输入关键词');
        return false;
      }

      this.loading = true;
      try {
        const response = await searchSubgraph(
          this.searchForm.selectedType, 
          this.searchForm.searchKeyword
        );
        
        if (!response || !response.data) {
          throw new Error('API返回数据格式不正确');
        }

        // 清空现有图数据
        this.graphData.nodes = [];
        this.graphData.edges = [];
        this.loadedNodeIds.clear();
        this.loadedEdgeKeys.clear();
        
        // 设置新数据
        this.setGraphData(response.data);
        
        ElMessage.success(`已加载${this.graphData.nodes.length}个节点和${this.graphData.edges.length}条关系`);
        return true;
      } catch (error) {
        console.error('搜索失败:', error);
        ElMessage.error('搜索失败');
        return false;
      } finally {
        this.loading = false;
      }
    },

    /**
     * 加载节点的一度邻居
     */
    async loadNodeNeighbors(nodeId: string) {
      this.loading = true;
      try {
        const response = await getNodeWithNeighbors(nodeId);
        
        if (!response || !response.data) {
          throw new Error('API返回数据格式不正确');
        }

        // 处理新节点和边
        this.addNewNodesAndEdges(response.data);
        return true;
      } catch (error) {
        console.error('加载邻居节点失败:', error);
        ElMessage.error('加载邻居节点失败');
        return false;
      } finally {
        this.loading = false;
      }
    },

    /**
     * 获取节点属性详情
     */
    async fetchNodeProperties(nodeId: string) {
      this.loading = true;
      try {
        const response = await getNodeProperties(nodeId);
        
        if (response && response.data) {
          this.nodeProperties = response.data;
        }
        return true;
      } catch (error) {
        console.error('获取节点属性失败:', error);
        ElMessage.error('获取节点属性失败');
        return false;
      } finally {
        this.loading = false;
      }
    },

    /**
     * 设置当前选中的节点
     */
    setCurrentNode(node: GraphNodeDTO | null) {
      this.currentNode = node;
    },

    /**
     * 获取边的唯一键
     * @param edge 边对象
     * @returns 唯一键
     */
    getEdgeKey(edge: GraphEdgeDTO): string {
      return `${edge.source}-${edge.target}-${edge.type}`;
    },

    /**
     * 检查边的源节点和目标节点是否都存在于当前图中
     * @param edge 边对象
     * @param nodeIds 节点ID集合
     * @returns 是否是有效的边
     */
    isValidEdge(edge: GraphEdgeDTO, nodeIds: Set<string>): boolean {
      return nodeIds.has(edge.source) && nodeIds.has(edge.target);
    },

    /**
     * 设置图数据
     */
    setGraphData(data: GraphDTO) {
      // 处理节点
      const nodes = data.nodes?.map(node => ({
        ...node,
        size: node.size || 40,
        style: {
          fill: node.color || '#C6E5FF',
          stroke: '#5B8FF9',
        }
      })) || [];

      // 记录节点ID用于验证边的有效性
      const nodeIds = new Set<string>();
      nodes.forEach(node => {
        nodeIds.add(node.id);
        this.loadedNodeIds.add(node.id);
      });

      // 处理边，过滤重复的边和无效的边
      const edges: any[] = [];
      data.edges?.forEach(edge => {
        // 检查是否是有效边（源节点和目标节点都存在）
        if (this.isValidEdge(edge, nodeIds)) {
          const edgeKey = this.getEdgeKey(edge);
          if (!this.loadedEdgeKeys.has(edgeKey)) {
            this.loadedEdgeKeys.add(edgeKey);
            edges.push({
              ...edge,
              label: edge.name,
              style: {
                lineWidth: 2,
              }
            });
          }
        }
      });

      this.graphData.nodes = nodes;
      this.graphData.edges = edges;
    },

    /**
     * 添加新节点和边
     */
    addNewNodesAndEdges(data: GraphDTO) {
      // 筛选出新的节点（排除已存在的）
      const newNodes = data.nodes.filter(node => !this.loadedNodeIds.has(node.id));
      
      // 记录所有节点ID，包括新节点和已有节点
      const allNodeIds = new Set<string>(this.loadedNodeIds);
      newNodes.forEach(node => allNodeIds.add(node.id));
      
      // 筛选出新的边（排除已存在的）且源节点和目标节点都在图中
      const newEdges: GraphEdgeDTO[] = [];
      data.edges.forEach(edge => {
        // 检查是否是有效边（源节点和目标节点都存在）
        if (this.isValidEdge(edge, allNodeIds)) {
          const edgeKey = this.getEdgeKey(edge);
          if (!this.loadedEdgeKeys.has(edgeKey)) {
            this.loadedEdgeKeys.add(edgeKey);
            newEdges.push(edge);
          }
        }
      });
      
      // 添加新节点
      const formattedNewNodes = newNodes.map(node => ({
        ...node,
        size: node.size || 40,
        style: {
          fill: node.color || '#C6E5FF',
          stroke: '#5B8FF9',
        }
      }));
      
      // 添加新边
      const formattedNewEdges = newEdges.map(edge => ({
        ...edge,
        label: edge.name,
        style: {
          lineWidth: 2,
        }
      }));
      
      // 更新状态
      this.graphData.nodes = [...this.graphData.nodes, ...formattedNewNodes];
      this.graphData.edges = [...this.graphData.edges, ...formattedNewEdges];
      
      // 记录已加载的节点ID
      newNodes.forEach(node => {
        this.loadedNodeIds.add(node.id);
      });
    }
  }
}); 